package com.lagou.server;

import com.lagou.config.ServerConfigUtil;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ZkServerHandler {

    @Autowired
    private ServerConfigUtil serverConfigUtil;


    public void registerToZk(int providerPort) throws Exception {
        String zkServerConnectUrl = serverConfigUtil.getZkServerConnectUrl();
        System.out.println("zookeeper 服务器链接地址：" + zkServerConnectUrl);

        RetryPolicy exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(zkServerConnectUrl)
                .sessionTimeoutMs(1000)
                .connectionTimeoutMs(10000)
                .retryPolicy(exponentialBackoffRetry)
                .build();

        client.start();


        //在zookeeper创建服务器根节点rpc-provider
        String serverZkBasePath = serverConfigUtil.getServerZkBasePath();

        //每个服务器的节点对应存储的数据为 ip:端口
        String serverData = "localhost:" + providerPort;

        Stat stat = client.checkExists().forPath(serverZkBasePath);
        if (stat == null) {
            String providerRootPath = client.create().creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(serverZkBasePath);
            System.out.println("注册服务器根节点到zookeeper上，节点路径：" + providerRootPath);
        }

        //每个服务器对应的节点为临时节点，这样服务器关闭后临时节点会被删除掉,从而客户端能够通过节点变更检测到服务端下线
        String providerServerPath = client.create().creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(serverZkBasePath + "/provider", serverData.getBytes());
        System.out.println("注册服务器临时节点到zookeeper上，节点路径：" + providerServerPath);
    }
}
